home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / math / ast51src.zip / WDRIVER.C < prev    next >
C/C++ Source or Header  |  1995-12-31  |  44KB  |  1,639 lines

  1. /*
  2. ** Astrolog (Version 5.10) File: wdriver.c
  3. **
  4. ** IMPORTANT NOTICE: The graphics database and chart display routines
  5. ** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen
  6. ** (Astara@msn.com). Permission is granted to freely use and
  7. ** distribute these routines provided one doesn't sell, restrict, or
  8. ** profit from them in any way. Modification is allowed provided these
  9. ** notices remain with any altered or edited versions of the program.
  10. **
  11. ** The main planetary calculation routines used in this program have
  12. ** been Copyrighted and the core of this program is basically a
  13. ** conversion to C of the routines created by James Neely as listed in
  14. ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
  15. ** available from Matrix Software. The copyright gives us permission to
  16. ** use the routines for personal use but not to sell them or profit from
  17. ** them in any way.
  18. **
  19. ** The PostScript code within the core graphics routines are programmed
  20. ** and Copyright (C) 1992-1993 by Brian D. Willoughby
  21. ** (brianw@sounds.wa.com). Conditions are identical to those above.
  22. **
  23. ** The extended accurate ephemeris databases and formulas are from the
  24. ** calculation routines in the program "Placalc" and are programmed and
  25. ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
  26. ** (alois@azur.ch). The use of that source code is subject to
  27. ** regulations made by Astrodienst Zurich, and the code is not in the
  28. ** public domain. This copyright notice must not be changed or removed
  29. ** by any user of this program.
  30. **
  31. ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
  32. ** X Window graphics initially programmed 10/23-29/1991.
  33. ** PostScript graphics initially programmed 11/29-30/1992.
  34. ** Last code change made 12/27/1995.
  35. */
  36.  
  37. #include "astrolog.h"
  38.  
  39.  
  40. #ifdef WIN
  41. char szFileName[cchSzMaxFile];
  42. char szFileTitle[cchSzMaxFile];
  43. char *szFileTemp = szFileTempCore;
  44.  
  45.  
  46. /*
  47. ******************************************************************************
  48. ** Windows Command Processing.
  49. ******************************************************************************
  50. */
  51.  
  52. /* Process one command line switch passed to the program dealing with the   */
  53. /* Windows features. This is just like the processing of each switch in the */
  54. /* main program, however here each switch has been prefixed with an 'W'.    */
  55.  
  56. int NProcessSwitchesW(argc, argv, pos, fOr, fAnd, fNot)
  57. int argc, pos;
  58. bool fOr, fAnd, fNot;
  59. char **argv;
  60. {
  61.   int darg = 0, i;
  62.   char sz[cchSzDef], ch1;
  63.  
  64.   ch1 = argv[0][pos+1];
  65.   switch (argv[0][pos]) {
  66.   case chNull:
  67.     if (argc <= 1) {
  68.       ErrorArgc("W");
  69.       return tcError;
  70.     }
  71.     i = atoi(argv[1]);
  72.     PostMessage(wi.hwnd, WM_COMMAND, i, 0L);
  73.     darg++;
  74.     break;
  75.  
  76.   case 'N':
  77.     if (argc <= 1) {
  78.       ErrorArgc("WN");
  79.       return tcError;
  80.     }
  81.     i = atoi(argv[1]);
  82.     if (!FValidTimer(i)) {
  83.       ErrorValN("WN", i);
  84.       return tcError;
  85.     }
  86.     wi.nTimerDelay = i;
  87.     darg++;
  88.     break;
  89.  
  90.   case 'M':
  91.     if (argc <= 2) {
  92.       ErrorArgc("WM");
  93.       return tcError;
  94.     }
  95.     i = atoi(argv[1]);
  96.     if (!FValidMacro(i)) {
  97.       ErrorValN("WM", i);
  98.       return tcError;
  99.     }
  100.     i--;
  101.     sprintf(sz, "%s\t%sF%d", argv[2], i < 12 ? "" : (i < 24 ? "Shift+" :
  102.       (i < 36 ? "Ctrl+" : "Alt+")), i % 12 + 1);
  103.     ModifyMenu(wi.hmenu, (WORD)(cmdMacro1 + i), MF_BYCOMMAND | MF_STRING,
  104.       (WORD)(cmdMacro1 + i), sz);
  105.     darg += 2;
  106.     break;
  107.  
  108.   default:
  109.     ErrorSwitch(argv[0]);
  110.     return tcError;
  111.   }
  112.   /* 'darg' contains the value to be added to argc when we return. */
  113.   return darg;
  114. }
  115.  
  116.  
  117. /* Change the pixel size of the window so its internal drawable area is the */
  118. /* dimensions of the current graphics chart. Both the upper left and lower  */
  119. /* right corners of the window may change depending on the scroll position. */
  120.  
  121. void ResizeWindowToChart()
  122. {
  123.   RECT rcOld, rcNew;
  124.   int xScr, yScr;
  125.   HDC hdc;
  126.  
  127.   if (!us.fGraphics || gs.xWin == 0 || gs.yWin == 0)
  128.     return;
  129.   GetWindowRect(wi.hwnd, &rcOld);
  130.   hdc = GetDC(wi.hwnd);
  131.   xScr = GetDeviceCaps(hdc, HORZRES);
  132.   yScr = GetDeviceCaps(hdc, VERTRES);
  133.   ReleaseDC(wi.hwnd, hdc);
  134.   rcNew.left = rcOld.left + gi.xOffset;
  135.   rcNew.top  = rcOld.top + gi.yOffset;
  136.   rcNew.right = rcNew.left + gs.xWin + (gi.nMode == 0 ? SIDESIZE : 0) + 23;
  137.   rcNew.bottom = rcNew.top + gs.yWin + 61;
  138.   if (rcNew.right > xScr)
  139.     OffsetRect(&rcNew, xScr - rcNew.right, 0);
  140.   if (rcNew.bottom > yScr)
  141.     OffsetRect(&rcNew, 0, yScr - rcNew.bottom);
  142.   if (rcNew.left < 0)
  143.     OffsetRect(&rcNew, -rcNew.left, 0);
  144.   if (rcNew.top < 0)
  145.     OffsetRect(&rcNew, 0, -rcNew.top);
  146.   MoveWindow(wi.hwnd, rcNew.left, rcNew.top,
  147.     rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, fTrue);
  148. }
  149.  
  150.  
  151. /* Given a relationship chart mode, return the menu command that sets it. */
  152.  
  153. WORD WCmdFromRc(int rc)
  154. {
  155.   switch (rc) {
  156.   case rcDual:       return cmdRelComparison;
  157.   case rcComposite:  return cmdRelComposite;
  158.   case rcMidpoint:   return cmdRelMidpoint;
  159.   case rcDifference: return cmdRelDate;
  160.   case rcBiorhythm:  return cmdRelBiorhythm;
  161.   case rcTransit:    return cmdRelTransit;
  162.   case rcProgress:   return cmdRelProgressed;
  163.   default:           return cmdRelNo;
  164.   }
  165. }
  166.  
  167.  
  168. /* Change relationship chart modes. Given a new mode, we put a check by its */
  169. /* menu command, and erase the check by the menu command for the old mode.  */
  170.  
  171. void SetRel(int rc)
  172. {
  173.   CheckMenu(WCmdFromRc(us.nRel), fFalse);
  174.   CheckMenu(WCmdFromRc(rc), fTrue);
  175.   us.nRel = rc;
  176.   wi.fCast = fTrue;
  177. }
  178.  
  179.  
  180. /* The main program, the starting point of Astrolog for Windows, follows.   */
  181. /* This is like the "main" function in standard C. The program initializes  */
  182. /* here, then spins in a tight message processing loop until it terminates. */
  183.  
  184. int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  185. HANDLE hInstance;
  186. HANDLE hPrevInstance;
  187. LPSTR lpszCmdLine;
  188. int nCmdShow;
  189. {
  190.   MSG msg;
  191.   WNDCLASS wndclass;
  192.  
  193.   /* Set up the window class shared by all instances of Astrolog. */
  194.  
  195.   wi.hinst = hInstance;
  196.   if (!hPrevInstance) {
  197.     ClearB((lpbyte)&wndclass, sizeof(WNDCLASS));
  198.     wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
  199.     wndclass.lpfnWndProc = WndProc;
  200.     wndclass.cbClsExtra = 0;
  201.     wndclass.cbWndExtra = 0;
  202.     wndclass.hInstance = wi.hinst;
  203.     wndclass.hIcon = LoadIcon(wi.hinst, MAKEINTRESOURCE(icon));
  204.     wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
  205.     wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  206.     wndclass.lpszMenuName = MAKEINTRESOURCE(menu);
  207.     wndclass.lpszClassName = szAppName;
  208.     if (!RegisterClass(&wndclass)) {
  209.       PrintError("The window class could not be registered.");
  210.       return -1L;
  211.     }
  212.   }
  213.  
  214.   /* Create the actual window to be used and drawn on by this instance. */
  215.  
  216.   wi.hmenu = LoadMenu(wi.hinst, MAKEINTRESOURCE(menu));
  217.   wi.hwndMain = CreateWindow(
  218.     szAppName,
  219.     "Astrolog 5.10",
  220.     WS_CAPTION |
  221.     WS_SYSMENU |
  222.     WS_MINIMIZEBOX |
  223.     WS_MAXIMIZEBOX |
  224.     WS_THICKFRAME |
  225.     WS_VSCROLL |
  226.     WS_HSCROLL |
  227.     WS_CLIPCHILDREN |
  228.     WS_OVERLAPPED,
  229.     CW_USEDEFAULT, 0,
  230.     CW_USEDEFAULT, 0,
  231.     (HWND)NULL,
  232.     wi.hmenu,
  233.     wi.hinst,
  234.     (LPSTR)NULL);
  235.   if (wi.hwndMain == (HWND)NULL) {
  236.     PrintError("The window could not be created.");
  237.     return -1L;
  238.   }
  239.  
  240.   /* Set up some globals that can't be initialized at compile time. */
  241.  
  242.   ofn.hwndOwner = wi.hwndMain;
  243.   ofn.lpstrFile = szFileName;
  244.   ofn.lpstrFileTitle = szFileTitle;
  245.   prd.hwndOwner = wi.hwndMain;
  246.   wi.haccel = LoadAccelerators(wi.hinst, MAKEINTRESOURCE(accelerator));
  247.   wi.kiPen = gi.kiLite;
  248.  
  249.   /* Process the astrolog.dat file and the Windows command line. */
  250.  
  251.   FProcessSwitchFile(DEFAULT_INFOFILE, NULL);
  252.   FProcessCommandLine(lpszCmdLine);
  253.   ciTwin = ciCore;
  254.  
  255.   /* Actually bring up and display the window for the first time. */
  256.  
  257.   ResizeWindowToChart();
  258.   ShowWindow(wi.hwndMain, nCmdShow);
  259.   RedoMenu();
  260.   wi.nTimer = SetTimer(wi.hwnd, 1, wi.nTimerDelay, NULL);
  261.  
  262.   /* Process window messages until the program is told to terminate. */
  263.  
  264.   while (GetMessage(&msg, (HWND)NULL, 0, 0)) {
  265.     if (!TranslateAccelerator(wi.hwndMain, wi.haccel, &msg))
  266.       TranslateMessage(&msg);
  267.     DispatchMessage(&msg);
  268.   }
  269.  
  270.   /* Cleanup and exit Astrolog for Windows. */
  271.  
  272.   UnregisterClass(szAppName, wi.hinst);
  273.   return msg.wParam;
  274. }
  275.  
  276.  
  277. /* This is the main message processor for the Astrolog window. Given a */
  278. /* user input or other message, do the appropriate action and updates. */
  279.  
  280. LONG API WndProc(hwnd, wMsg, wParam, lParam)
  281. HWND hwnd;
  282. WORD wMsg;
  283. WORD wParam;
  284. LONG lParam;
  285. {
  286.   HDC hdc;
  287.   HPEN hpen, hpenOld;
  288.   HBRUSH hbr;
  289.   RECT rc;
  290.   int x, y;
  291.  
  292.   wi.hwnd = hwnd;
  293.   switch (wMsg) {
  294.  
  295.     /* A command, most likely a menu option, was given. */
  296.  
  297.     case WM_COMMAND:
  298.       switch (NWmCommand(wParam)) {
  299.       case 1:
  300.         goto LWM_CLOSE;
  301.       case -1:
  302.         return DefWindowProc(hwnd, wMsg, wParam, lParam);
  303.       default:
  304.         ProcessState();
  305.       }
  306.       break;
  307.  
  308.     /* When a part of a window is uncovered, Windows quickly blanks it out, */
  309.     /* usually with white, before having the app redraw that section. Most  */
  310.     /* apps don't do anything here, however Astrolog can quickly draw with  */
  311.     /* a more appropriate color since we know our chart's background color. */
  312.  
  313.     case WM_ERASEBKGND:
  314.       GetClipBox((HDC)wParam, &rc);
  315.       hbr = CreateSolidBrush(rgbbmp[gs.fInverse ? kWhite : kBlack]);
  316.       FillRect((HDC)wParam, &rc, hbr);
  317.       DeleteObject(hbr);
  318.       return fTrue;
  319.  
  320.     /* The window was just created. Setup the scrollbars. */
  321.  
  322.     case WM_CREATE:
  323.       SetScrollRange(hwnd, SB_HORZ, 0, nScrollDiv, fFalse);
  324.       SetScrollRange(hwnd, SB_VERT, 0, nScrollDiv, fFalse);
  325.       break;
  326.  
  327.     /* The window has been resized. Change the chart size if need be. */
  328.  
  329.     case WM_SIZE:
  330.       wi.xClient = LOWORD(lParam);
  331.       wi.yClient = HIWORD(lParam);
  332.       if (wi.fWindowChart || wi.fChartWindow) {
  333.         gs.xWin = wi.xClient; gs.yWin = wi.yClient;
  334.       }
  335.       break;
  336.  
  337.     /* All or part of the window needs to be redrawn. Go do so. */
  338.  
  339.     case WM_PAINT:
  340.       FRedraw();
  341.       break;
  342.  
  343.     /* The mouse has been left clicked or dragged over the window. */
  344.  
  345.     case WM_LBUTTONDOWN:
  346.     case WM_MOUSEMOVE:
  347.  
  348.       /* Treat dragging with the mouse down as a Shift+left click. */
  349.       if (wMsg == WM_MOUSEMOVE) {
  350.         if ((wParam & MK_LBUTTON) == 0 ||
  351.           (wParam & MK_SHIFT) || (wParam & MK_CONTROL))
  352.           break;
  353.         wParam = MK_SHIFT;
  354.       }
  355.       x = WLo(lParam);
  356.       y = WHi(lParam);
  357.  
  358.       /* Alt+click on a world map chart means relocate the chart there. */
  359.       if (wMsg == WM_LBUTTONDOWN && GetKeyState(VK_MENU) < 0) {
  360.         if (fMap && gs.nRot == 0 && !gs.fConstel && !gs.fMollewide) {
  361.           Lon = DegToDec(rDegHalf-(real)(x-gi.xOffset)/(real)gs.xWin*rDegMax);
  362.           if (Lon < -rDegHalf)
  363.             Lon = -rDegHalf;
  364.           else if (Lon > rDegHalf)
  365.             Lon = rDegHalf;
  366.           Lat = DegToDec(rDegQuad-(real)(y-gi.yOffset)/(real)gs.yWin*180.0);
  367.           if (Lat < -rDegQuad)
  368.             Lat = -rDegQuad;
  369.           else if (Lat > rDegQuad)
  370.             Lat = rDegQuad;
  371.           wi.xMouse = -1;
  372.           wi.fCast = fTrue;
  373.         }
  374.         break;
  375.       }
  376.       hdc = GetDC(hwnd);
  377.       hpen = CreatePen(PS_SOLID, 0, (COLORREF)rgbbmp[wi.kiPen]);
  378.       hpenOld = SelectObject(hdc, hpen);
  379.  
  380.       /* Ctrl+click means draw a rectangle. Ctrl+Shift+click does ellipse. */
  381.       if (wParam & MK_CONTROL) {
  382.         SelectObject(hdc, GetStockObject(NULL_BRUSH));
  383.         if (wParam & MK_SHIFT)
  384.           Ellipse(hdc, wi.xMouse, wi.yMouse, x, y);
  385.         else
  386.           Rectangle(hdc, wi.xMouse, wi.yMouse, x, y);
  387.  
  388.       /* Shift+click means draw a line from the last to current position. */
  389.       } else if (wParam & MK_SHIFT) {
  390.         if (wi.xMouse >= 0) {
  391.           MoveTo(hdc, wi.xMouse, wi.yMouse);
  392.           LineTo(hdc, x, y);
  393.           if (wMsg == WM_MOUSEMOVE) {
  394.             wi.xMouse = x; wi.yMouse = y;
  395.           }
  396.         }
  397.  
  398.       /* A simple click means set a pixel and remember that location. */
  399.       } else {
  400.         SetPixel(hdc, x, y, (COLORREF)rgbbmp[wi.kiPen]);
  401.         wi.xMouse = x; wi.yMouse = y;
  402.       }
  403.       SelectObject(hdc, hpenOld);
  404.       DeleteObject(hpen);
  405.       ReleaseDC(hwnd, hdc);
  406.       break;
  407.  
  408.     /* The mouse has been right clicked on the window. If on a world map  */
  409.     /* or astro-graph chart, relocate the chart to the mouse coordinates. */
  410.  
  411.     case WM_RBUTTONDOWN:
  412.       x = WLo(lParam);
  413.       y = WHi(lParam);
  414.       if (us.fGraphics && (us.fAstroGraph || gi.nMode == gWorldMap) &&
  415.         gs.nRot == 0 && !gs.fConstel && !gs.fMollewide) {
  416.         Lon = DegToDec(rDegHalf-(real)(x-gi.xOffset)/
  417.           (real)gs.xWin*rDegMax);
  418.         if (Lon < -rDegHalf)
  419.           Lon = -rDegHalf;
  420.         else if (Lon > rDegHalf)
  421.           Lon = rDegHalf;
  422.         Lat = DegToDec(rDegQuad-(real)(y-gi.yOffset)/
  423.           (real)gs.yWin*181.0);
  424.         if (Lat < -rDegQuad)
  425.           Lat = -rDegQuad;
  426.         else if (Lat > rDegQuad)
  427.           Lat = rDegQuad;
  428.         ciCore = ciMain;
  429.         wi.fCast = fTrue;
  430.         ProcessState();
  431.       }
  432.       break;
  433.  
  434.     /* A timer message is received at a defined regular interval. */
  435.  
  436.     case WM_TIMER:
  437.       if (!gs.nAnim || wi.fPause)
  438.         break;
  439.       Animate(gs.nAnim, wi.nDir);  /* Update chart if animation mode on. */
  440.       wi.fRedraw = fTrue;
  441.       ProcessState();
  442.       break;
  443.  
  444.     /* Define the minimum and maximum size the window may be resized to. */
  445.  
  446.     case WM_GETMINMAXINFO:
  447.       ((MINMAXINFO FAR *)lParam)->ptMinTrackSize.x = BITMAPX1;
  448.       ((MINMAXINFO FAR *)lParam)->ptMinTrackSize.y = BITMAPY1;
  449.       ((MINMAXINFO FAR *)lParam)->ptMaxTrackSize.x = BITMAPX;
  450.       ((MINMAXINFO FAR *)lParam)->ptMaxTrackSize.x = BITMAPY;
  451.       break;
  452.  
  453.     /* The horizontal scrollbar was clicked on or used in some way. */
  454.  
  455.     case WM_HSCROLL:
  456.       x = wi.xScroll;
  457.       switch (wParam) {
  458.       case SB_LINEUP:
  459.         wi.xScroll--;
  460.         break;
  461.       case SB_LINEDOWN:
  462.         wi.xScroll++;
  463.         break;
  464.       case SB_PAGEUP:
  465.         wi.xScroll -= nScrollPage;
  466.         break;
  467.       case SB_PAGEDOWN:
  468.         wi.xScroll += nScrollPage;
  469.         break;
  470.       case SB_THUMBPOSITION:
  471.         wi.xScroll = LOWORD(lParam);
  472.         break;
  473.       default:
  474.         return fFalse;
  475.       }
  476.       wi.xScroll = max(0, min(wi.xScroll, nScrollDiv));
  477.       if (wi.xScroll == x)
  478.         break;
  479.       SetScrollPos(hwnd, SB_HORZ, wi.xScroll, fTrue);
  480.       wi.fRedraw = fTrue;
  481.       ProcessState();
  482.       break;
  483.  
  484.     /* The vertical scrollbar was clicked on or used in some way. */
  485.  
  486.     case WM_VSCROLL:
  487.       y = wi.yScroll;
  488.       switch(wParam) {
  489.       case SB_LINEUP:
  490.         wi.yScroll--;
  491.         break;
  492.       case SB_LINEDOWN:
  493.         wi.yScroll++;
  494.         break;
  495.       case SB_PAGEUP:
  496.         wi.yScroll -= nScrollPage;
  497.         break;
  498.       case SB_PAGEDOWN:
  499.         wi.yScroll += nScrollPage;
  500.         break;
  501.       case SB_THUMBPOSITION:
  502.         wi.yScroll = LOWORD(lParam);
  503.         break;
  504.       default:
  505.         return fFalse;
  506.       }
  507.       wi.yScroll = max(0, min(wi.yScroll, nScrollDiv));
  508.       if (wi.yScroll == y)
  509.         break;
  510.       SetScrollPos(hwnd, SB_VERT, wi.yScroll, fTrue);
  511.       wi.fRedraw = fTrue;
  512.       ProcessState();
  513.       break;
  514.  
  515.     /* The window is being terminated. Clean up and free program data. */
  516.  
  517.     case WM_CLOSE:
  518. LWM_CLOSE:
  519.       if (us.fNoQuit) {
  520.         PrintWarning("Program exiting is not allowed now.");
  521.         break;
  522.       }
  523.       if (wi.hpen != (HPEN)NULL)
  524.         DeleteObject(wi.hpen);
  525.       if (wi.nTimer != 0)
  526.         KillTimer(hwnd, 1);
  527.       DestroyWindow(hwnd);
  528.       if (hwnd == wi.hwndMain)
  529.         PostQuitMessage(0);
  530.       break;
  531.  
  532.     /* Messages not processed here are handled by Windows in a default way. */
  533.  
  534.     default:
  535.       return DefWindowProc(hwnd, wMsg, wParam, lParam);
  536.     }
  537.   return fFalse;
  538. }
  539.  
  540.  
  541. /* This is called after some action has been done that probably changed the */
  542. /* chart state, such as a menu command was run. Update anything needing it. */
  543.  
  544. void ProcessState()
  545. {
  546.   if (wi.fMenuAll) {       /* Redetermine all menu checks if need be. */
  547.     RedoMenu();
  548.     wi.fMenu = fTrue;
  549.   }
  550.   if (wi.fMenu) {          /* Update menu if we added/removed check marks. */
  551.     DrawMenuBar(wi.hwnd);
  552.     wi.fMenu = fFalse;
  553.   }
  554.   if (wi.fCast)            /* Recasting a chart implies redrawing it too. */
  555.     wi.fRedraw = fTrue;
  556.  
  557.   /* If the chart type was changed, clear all the setting flags, then set */
  558.   /* the appropriate core switch settings based on the new chart type.    */
  559.  
  560.   if (wi.nMode) {
  561.     ClearB((lpbyte)&us.fListing,
  562.       (int)((lpbyte)&us.fVelocity - (lpbyte)&us.fListing));
  563.     ClearB((lpbyte)&us.fCredit,
  564.       (int)((lpbyte)&us.fLoop - (lpbyte)&us.fCredit));
  565.     us.nArabic = gi.nMode = 0;
  566.     switch (wi.nMode) {
  567.       case gBiorhythm:
  568.       case gWheel:      us.fListing    = fTrue; break;
  569.       case gHouse:      us.fWheel      = fTrue; break;
  570.       case gGrid:       us.fGrid       = fTrue; break;
  571.       case gHorizon: us.fHorizon = fTrue; us.fHorizonSearch = fFalse; break;
  572.       case gOrbit:      us.fOrbit      = fTrue; break;
  573.       case gAstroGraph: us.fAstroGraph = fTrue; break;
  574.       case gEphemeris:  us.fEphemeris  = fTrue; break;
  575.       case gWorldMap:   gi.nMode = gWorldMap; break;
  576.       case gGlobe:      gi.nMode = gGlobe;    break;
  577.       case gPolar:      gi.nMode = gPolar;    break;
  578.       case gCalendar:   us.fCalendar   = fTrue; break;
  579.       case gDisposit:   us.fInfluence  = fTrue; break;
  580.       case gAspect:     us.fAspList    = fTrue; break;
  581.       case gMidpoint:   us.fMidpoint   = fTrue; break;
  582.       case gArabic:     us.nArabic     = 1; break;
  583.       case gSign:       us.fSign       = fTrue; break;
  584.       case gObject:     us.fObject     = fTrue; break;
  585.       case gHelpAsp:    us.fAspect     = fTrue; break;
  586.       case gConstel:    us.fConstel    = fTrue; break;
  587.       case gPlanet:     us.fOrbitData  = fTrue; break;
  588.       case gMeaning:    us.fMeaning    = fTrue; break;
  589.       case gSwitch:     us.fSwitch     = fTrue; break;
  590.       case gObscure:    us.fSwitchRare = fTrue; break;
  591.       case gKeystroke:  us.fKeyGraph   = fTrue; break;
  592.       case gCredit:     us.fCredit     = fTrue; break;
  593.       case gRising:     us.fHorizon = us.fHorizonSearch = fTrue; break;
  594.       case gTraTraHit:  us.fInDay      = fTrue; break;
  595.       case gTraTraInf:  us.fInDayInf   = fTrue; break;
  596.       case gTraNatHit:  us.fTransit    = fTrue; break;
  597.       case gTraNatInf:  us.fTransitInf = fTrue; break;
  598.     }
  599.     wi.nMode = 0;
  600.     wi.fRedraw = fTrue;
  601.   }
  602.   if (wi.fRedraw)    /* Send the window a redraw message if need be. */
  603.     RedrawWindow(wi.hwnd, NULL, (HRGN)NULL, RDW_INVALIDATE);
  604. }
  605.  
  606.  
  607. /* Given a command, process it, changing any appropriate program settings. */
  608. /* Return values are 0, meaning it was one of Astrolog's menu commands and */
  609. /* action was taken; 1, meaning it's the special end program command; or   */
  610. /* -1, meaning it's not a custom command and Windows can deal with it.     */
  611.  
  612. int NWmCommand(wCmd)
  613. WORD wCmd;
  614. {
  615.   char sz[cchSzDef];
  616.   DLGPROC dlgproc;
  617.   int i;
  618.   long l;
  619.   bool fGraphics, fT;
  620.  
  621.   wi.wCmd = wCmd;
  622.   fGraphics = us.fGraphics;
  623.   switch (wCmd) {
  624.  
  625.   /* File Menu */
  626.  
  627.   case cmdFileExit:
  628.     return 1;
  629.  
  630.   case cmdOpenChart:
  631.   case cmdOpenChart2:
  632.     DlgOpenChart();
  633.     break;
  634.  
  635.   case cmdSaveChart:
  636.   case cmdSavePositions:
  637.   case cmdSaveText:
  638.   case cmdSaveBitmap:
  639. #ifdef META
  640.   case cmdSavePicture:
  641. #endif
  642. #ifdef PS
  643.   case cmdSavePS:
  644. #endif
  645.   case cmdSaveSettings:
  646.   case cmdSaveWallTile:
  647.   case cmdSaveWallCenter:
  648.     DlgSaveChart();
  649.     break;
  650.  
  651.   case cmdPrint:
  652.     if (!DlgPrint())
  653.       PrintWarning("The printing was not completed successfully.");
  654.     break;
  655.  
  656.   case cmdPrintSetup:
  657.     l = prd.Flags;
  658.     prd.Flags |= PD_PRINTSETUP;
  659.     PrintDlg((LPPRINTDLG)&prd);
  660.     prd.Flags = l;
  661.     break;
  662.  
  663.   /* Edit Menu */
  664.  
  665.   case cmdCommand:
  666.     WiDoDialog(DlgCommand, dlgCommand);
  667.     break;
  668.  
  669.   case cmdColor:
  670.     WiDoDialog(DlgColor, dlgColor);
  671.     break;
  672.  
  673.   case cmdCopyText:
  674.     is.szFileScreen = szFileTemp;
  675.     us.fGraphics = fFalse;
  676.     wi.fRedraw = fTrue;
  677.     break;
  678.  
  679.   case cmdCopyBitmap:
  680. #ifdef META
  681.   case cmdCopyPicture:
  682. #endif
  683. #ifdef PS
  684.   case cmdCopyPS:
  685. #endif
  686.     if (us.fNoWrite)
  687.       break;
  688.     gi.szFileOut = szFileTemp;
  689.     gs.fBitmap = wi.wCmd == cmdCopyBitmap;
  690.     gs.fMeta = wi.wCmd == cmdCopyPicture;
  691.     gs.fPS = wi.wCmd == cmdCopyPS;
  692.     if (wCmd == cmdCopyBitmap)
  693.       gs.chBmpMode = 'B';
  694.     us.fGraphics = wi.fRedraw = fTrue;
  695.     break;
  696.  
  697.   /* View Menu */
  698.  
  699.   case cmdGraphics:
  700.     not(us.fGraphics);
  701.     wi.fRedraw = fTrue;
  702.     break;
  703.  
  704.   case cmdColoredText:
  705.     not(us.fAnsi);
  706.     WiCheckMenu(cmdColoredText, us.fAnsi);
  707.     us.fGraphics = fFalse;
  708.     wi.fRedraw = fTrue;
  709.     break;
  710.  
  711.   case cmdWinBuffer:
  712.     not(wi.fBuffer);
  713.     WiCheckMenu(cmdWinBuffer, wi.fBuffer);
  714.     break;
  715.  
  716.   case cmdWinRedraw:
  717.     wi.fMenuAll = wi.fRedraw = fTrue;
  718.     break;
  719.  
  720.   case cmdWinClear:
  721.     fT = gs.fJetTrail;
  722.     gs.fJetTrail = fFalse;
  723.     wi.hdc = GetDC(wi.hwnd);
  724.     if (us.fGraphics)
  725.       DrawClearScreen();
  726.     else
  727.       TextClearScreen();
  728.     ReleaseDC(wi.hwnd, wi.hdc);
  729.     gs.fJetTrail = fT;
  730.     break;
  731.  
  732.   case cmdWinHourglass:
  733.     not(wi.fHourglass);
  734.     WiCheckMenu(cmdWinHourglass, wi.fHourglass);
  735.     break;
  736.  
  737.   case cmdChartResizesWindow:
  738.     not(wi.fChartWindow);
  739.     WiCheckMenu(cmdChartResizesWindow, wi.fChartWindow);
  740.     wi.fRedraw = fTrue;
  741.     break;
  742.  
  743.   case cmdWindowResizesChart:
  744.     not(wi.fWindowChart);
  745.     WiCheckMenu(cmdWindowResizesChart, wi.fWindowChart);
  746.     wi.fRedraw = fTrue;
  747.     break;
  748.  
  749.   case cmdSizeChartToWindow:
  750.     gs.xWin = wi.xClient;
  751.     gs.yWin = wi.yClient;
  752.     us.fGraphics = wi.fRedraw = fTrue;
  753.     break;
  754.  
  755.   case cmdSizeWindowToChart:
  756.     ResizeWindowToChart();
  757.     break;
  758.  
  759.   case cmdScrollPageUp:
  760.     PostMessage(wi.hwnd, WM_VSCROLL, SB_PAGEUP, 0);
  761.     break;
  762.  
  763.   case cmdScrollPageDown:
  764.     PostMessage(wi.hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
  765.     break;
  766.  
  767.   case cmdScrollHome:
  768.     PostMessage(wi.hwnd, WM_HSCROLL, SB_THUMBPOSITION, 0);
  769.     PostMessage(wi.hwnd, WM_VSCROLL, SB_THUMBPOSITION, 0);
  770.     break;
  771.  
  772.   case cmdScrollEnd:
  773.     PostMessage(wi.hwnd, WM_HSCROLL, SB_THUMBPOSITION, nScrollDiv);
  774.     PostMessage(wi.hwnd, WM_VSCROLL, SB_THUMBPOSITION, nScrollDiv);
  775.     break;
  776.  
  777. #ifdef INTERPRET
  778.   case cmdInterpret:
  779.     not(us.fInterpret);
  780.     WiCheckMenu(cmdInterpret, us.fInterpret);
  781.     us.fGraphics = fFalse;
  782.     wi.fRedraw = fTrue;
  783.     break;
  784. #endif
  785.  
  786.   case cmdSecond:
  787.     not(us.fSeconds);
  788.     is.fSeconds = us.fSeconds;
  789.     WiCheckMenu(cmdSecond, us.fSeconds);
  790.     wi.fRedraw = fTrue;
  791.     break;
  792.  
  793.   case cmdApplying:
  794.     not(us.fAppSep);
  795.     WiCheckMenu(cmdApplying, us.fAppSep);
  796.     wi.fRedraw = fTrue;
  797.     break;
  798.  
  799.   case cmdParallel:
  800.     not(us.fParallel);
  801.     WiCheckMenu(cmdParallel, us.fParallel);
  802.     wi.fRedraw = fTrue;
  803.     break;
  804.  
  805.   /* Info Menu */
  806.  
  807.   case cmdSetInfo:
  808.   case cmdSetInfo2:
  809.     WiDoDialog(DlgInfo, dlgInfo);
  810.     break;
  811.  
  812. #ifdef TIME
  813.   case cmdNow:
  814.     FInputData(szNowCore);
  815.     wi.fCast = fTrue;
  816.     break;
  817. #endif
  818.  
  819.   case cmdDefaultInfo:
  820.     WiDoDialog(DlgDefault, dlgDefault);
  821.     break;
  822.  
  823.   case cmdRelNo:
  824.   case cmdRelComparison:
  825.     SetRel(us.nRel ? 0 : rcDual);
  826.     break;
  827.  
  828.   case cmdRelSynastry:
  829.     SetRel(rcSynastry);
  830.     break;
  831.  
  832.   case cmdRelComposite:
  833.     SetRel(rcComposite);
  834.     break;
  835.  
  836.   case cmdRelMidpoint:
  837.     SetRel(rcMidpoint);
  838.     break;
  839.  
  840.   case cmdRelDate:
  841.     SetRel(rcDifference);
  842.     gi.nMode = gWheel;
  843.     us.fGraphics = fFalse;
  844.     break;
  845.  
  846. #ifdef BIORHYTHM
  847.   case cmdRelBiorhythm:
  848.     SetRel(rcBiorhythm);
  849.     gi.nMode = gBiorhythm;
  850.     break;
  851. #endif
  852.  
  853.   case cmdRelTransit:
  854.     SetRel(rcTransit);
  855.     break;
  856.  
  857.   case cmdRelProgressed:
  858.     SetRel(rcProgress);
  859.     break;
  860.  
  861.   /* Settings Menu */
  862.  
  863.   case cmdSidereal:
  864.     not(us.fSidereal);
  865.     WiCheckMenu(cmdSidereal, us.fSidereal);
  866.     wi.fCast = fTrue;
  867.     break;
  868.  
  869.   case cmdHeliocentric:
  870.     not(us.objCenter);
  871.     WiCheckMenu(cmdHeliocentric, us.objCenter != 1);
  872.     wi.fCast = fTrue;
  873.     break;
  874.  
  875.   case cmdHouse0:
  876.   case cmdHouse1:
  877.   case cmdHouse2:
  878.   case cmdHouse3:
  879.   case cmdHouse4:
  880.   case cmdHouse5:
  881.   case cmdHouse6:
  882.   case cmdHouse7:
  883.   case cmdHouse8:
  884.   case cmdHouse9:
  885.   case cmdHouse10:
  886.   case cmdHouse11:
  887.   case cmdHouse12:
  888.   case cmdHouse13:
  889.     WiCheckMenu(cmdHouse0 + us.nHouseSystem, fFalse);
  890.     us.nHouseSystem = (int)(wCmd - cmdHouse0);
  891.     WiCheckMenu(wCmd, fTrue);
  892.     wi.fCast = fTrue;
  893.     break;
  894.  
  895.   case cmdHouseSetSolar:
  896.     not(us.objOnAsc);
  897.     WiCheckMenu(cmdHouseSetSolar, us.objOnAsc);
  898.     wi.fCast = fTrue;
  899.     break;
  900.  
  901.   case cmdHouseSetDecan:
  902.     not(us.fDecan);
  903.     WiCheckMenu(cmdHouseSetDecan, us.fDecan);
  904.     wi.fCast = fTrue;
  905.     break;
  906.  
  907.   case cmdHouseSetFlip:
  908.     not(us.fFlip);
  909.     WiCheckMenu(cmdHouseSetFlip, us.fFlip);
  910.     wi.fCast = fTrue;
  911.     break;
  912.  
  913.   case cmdHouseSetGeodetic:
  914.     not(us.fGeodetic);
  915.     WiCheckMenu(cmdHouseSetGeodetic, us.fGeodetic);
  916.     wi.fCast = fTrue;
  917.     break;
  918.  
  919.   case cmdAspect:
  920.     WiDoDialog(DlgAspect, dlgAspect);
  921.     break;
  922.  
  923.   case cmdObject:
  924.     WiDoDialog(DlgObject, dlgObject);
  925.     break;
  926.  
  927.   case cmdObject2:
  928.     WiDoDialog(DlgObject2, dlgObject2);
  929.     break;
  930.  
  931.   case cmdRes:
  932.   case cmdResTransit:
  933.     WiDoDialog(DlgRestrict, dlgRestrict);
  934.     break;
  935.  
  936.   case cmdResMinor:
  937.     for (i = oChi; i <= oVes; i++)
  938.       not(ignore[i]);
  939.     for (i = oLil; i <= oEP; i++)
  940.       not(ignore[i]);
  941.     WiCheckMenu(cmdResMinor, !ignore[oChi]);
  942.     wi.fCast = fTrue;
  943.     break;
  944.  
  945.   case cmdResCusp:
  946.     not(us.fCusp);
  947.     for (i = cuspLo; i <= cuspHi; i++)
  948.       ignore[i] = !us.fCusp || !ignore[i];
  949.     WiCheckMenu(cmdResCusp, us.fCusp);
  950.     wi.fCast = fTrue;
  951.     break;
  952.  
  953.   case cmdResUranian:
  954.     not(us.fUranian);
  955.     for (i = uranLo; i <= uranHi; i++)
  956.       ignore[i] = !us.fUranian || !ignore[i];
  957.     WiCheckMenu(cmdResUranian, us.fUranian);
  958.     wi.fCast = fTrue;
  959.     break;
  960.  
  961.   case cmdResStar:
  962.     us.nStar = !us.nStar;
  963.     for (i = starLo; i <= starHi; i++)
  964.       ignore[i] = !us.nStar || !ignore[i];
  965.     WiCheckMenu(cmdResStar, us.nStar);
  966.     wi.fCast = fTrue;
  967.     break;
  968.  
  969.   case cmdStar:
  970.     WiDoDialog(DlgStar, dlgStar);
  971.     break;
  972.  
  973.   case cmdSettingMore:
  974.     WiDoDialog(DlgSetting, dlgSetting);
  975.     break;
  976.  
  977.   case cmdObscure:
  978.     WiDoDialog(DlgObscure, dlgObscure);
  979.     break;
  980.  
  981.   /* Chart Menu */
  982.  
  983.   case cmdChartList:
  984.     wi.nMode = gWheel;
  985.     break;
  986.  
  987.   case cmdChartWheel:
  988.     wi.nMode = gHouse;
  989.     break;
  990.  
  991.   case cmdChartGrid:
  992.     wi.nMode = gGrid;
  993.     break;
  994.  
  995.   case cmdChartAspect:
  996.     wi.nMode = gAspect;
  997.     us.fGraphics = fFalse;
  998.     break;
  999.  
  1000.   case cmdChartMidpoint:
  1001.     wi.nMode = gMidpoint;
  1002.     us.fGraphics = fFalse;
  1003.     break;
  1004.  
  1005.   case cmdChartHorizon:
  1006.     wi.nMode = gHorizon;
  1007.     break;
  1008.  
  1009.   case cmdChartOrbit:
  1010.     wi.nMode = gOrbit;
  1011.     break;
  1012.  
  1013.   case cmdChartCalendar:
  1014.     wi.nMode = gCalendar;
  1015.     break;
  1016.  
  1017.   case cmdChartInfluence:
  1018.     wi.nMode = gDisposit;
  1019.     break;
  1020.  
  1021.   case cmdChartAstroGraph:
  1022.     wi.nMode = gAstroGraph;
  1023.     break;
  1024.  
  1025.   case cmdChartEphemeris:
  1026.     wi.nMode = gEphemeris;
  1027.     break;
  1028.  
  1029. #ifdef ARABIC
  1030.   case cmdChartArabic:
  1031.     wi.nMode = gArabic;
  1032.     us.fGraphics = fFalse;
  1033.     break;
  1034. #endif
  1035.  
  1036.   case cmdChartRising:
  1037.     wi.nMode = gRising;
  1038.     us.fGraphics = fFalse;
  1039.     break;
  1040.  
  1041.   case cmdProgress:
  1042.     WiDoDialog(DlgProgress, dlgProgress);
  1043.     break;
  1044.  
  1045.   case cmdTransit:
  1046.     WiDoDialog(DlgTransit, dlgTransit);
  1047.     break;
  1048.  
  1049.   case cmdChartSettings:
  1050.     WiDoDialog(DlgChart, dlgChart);
  1051.     break;
  1052.  
  1053.   /* Graphics Menu */
  1054.  
  1055.   case cmdChartMap:
  1056.     wi.nMode = gWorldMap;
  1057.     us.fGraphics = wi.fRedraw = fTrue;
  1058.     break;
  1059.  
  1060.   case cmdChartGlobe:
  1061.     wi.nMode = gGlobe;
  1062.     us.fGraphics = wi.fRedraw = fTrue;
  1063.     break;
  1064.  
  1065.   case cmdChartPolar:
  1066.     wi.nMode = gPolar;
  1067.     us.fGraphics = wi.fRedraw = fTrue;
  1068.     break;
  1069.  
  1070. #ifdef CONSTEL
  1071.   case cmdConstellation:
  1072.     if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar)
  1073.       wi.nMode = gWorldMap;
  1074.     not(gs.fConstel);
  1075.     WiCheckMenu(cmdConstellation, gs.fConstel);
  1076.     us.fGraphics = wi.fRedraw = fTrue;
  1077.     break;
  1078. #endif
  1079.  
  1080.   case cmdGraphicsReverse:
  1081.     not(gs.fInverse);
  1082.     WiCheckMenu(cmdGraphicsReverse, gs.fInverse);
  1083.     us.fGraphics = wi.fRedraw = fTrue;
  1084.     break;
  1085.  
  1086.   case cmdGraphicsMonochrome:
  1087.     not(gs.fColor);
  1088.     WiCheckMenu(cmdGraphicsMonochrome, !gs.fColor);
  1089.     us.fGraphics = wi.fRedraw = fTrue;
  1090.     break;
  1091.  
  1092.   case cmdGraphicsBorder:
  1093.     not(gs.fBorder);
  1094.     WiCheckMenu(cmdGraphicsBorder, gs.fBorder);
  1095.     us.fGraphics = wi.fRedraw = fTrue;
  1096.     break;
  1097.  
  1098.   case cmdGraphicsText:
  1099.     not(gs.fText);
  1100.     WiCheckMenu(cmdGraphicsText, gs.fText);
  1101.     us.fGraphics = wi.fRedraw = fTrue;
  1102.     break;
  1103.  
  1104.   case cmdGraphicsSidebar:
  1105.     not(us.fVelocity);
  1106.     if (!us.fVelocity) {
  1107.       gs.fText = fTrue;
  1108.       WiCheckMenu(cmdGraphicsText, fTrue);
  1109.     }
  1110.     WiCheckMenu(cmdGraphicsSidebar, !us.fVelocity);
  1111.     wi.nMode = gWheel;
  1112.     us.fGraphics = wi.fRedraw = fTrue;
  1113.     break;
  1114.  
  1115.   case cmdGraphicsLabel:
  1116.     not(gs.fLabel);
  1117.     WiCheckMenu(cmdGraphicsLabel, gs.fLabel);
  1118.     us.fGraphics = wi.fRedraw = fTrue;
  1119.     break;
  1120.  
  1121.   case cmdGraphicsSquare:
  1122.     SquareX(&gs.xWin, &gs.yWin, fTrue);
  1123.     ResizeWindowToChart();
  1124.     us.fGraphics = wi.fRedraw = fTrue;
  1125.     break;
  1126.  
  1127.   case cmdScale1:
  1128.   case cmdScale2:
  1129.   case cmdScale3:
  1130.   case cmdScale4:
  1131.     WiCheckMenu(cmdScale1 + gs.nScale/100 - 1, fFalse);
  1132.     gs.nScale = (int)(wCmd - cmdScale1) + 1;
  1133.     gs.nScale *= 100;
  1134.     WiCheckMenu(wCmd, fTrue);
  1135.     wi.fRedraw = fTrue;
  1136.     break;
  1137.  
  1138.   case cmdScaleDecrease:
  1139.     if (gs.nScale > 100) {
  1140.       WiCheckMenu(cmdScale1 + gs.nScale/100 - 1, fFalse);
  1141.       gs.nScale -= 100;
  1142. LScale:
  1143.       WiCheckMenu(cmdScale1 + gs.nScale/100 - 1, fTrue);
  1144.       wi.fRedraw = fTrue;
  1145.     }
  1146.     break;
  1147.  
  1148.   case cmdScaleIncrease:
  1149.     if (gs.nScale < MAXSCALE) {
  1150.       WiCheckMenu(cmdScale1 + gs.nScale/100 - 1, fFalse);
  1151.       gs.nScale += 100;
  1152.       goto LScale;
  1153.     }
  1154.     break;
  1155.  
  1156.   case cmdTiltZero:
  1157.     if (gi.nMode != gGlobe)
  1158.       wi.nMode = gGlobe;
  1159.     if (gs.rTilt != 0.0) {
  1160.       gs.rTilt = 0.0;
  1161.       wi.fRedraw = fTrue;
  1162.     }
  1163.     us.fGraphics = fTrue;
  1164.     break;
  1165.  
  1166.   case cmdTiltDecrease:
  1167.     if (gi.nMode != gGlobe)
  1168.       wi.nMode = gGlobe;
  1169.     if (gs.rTilt > -rDegQuad) {
  1170.       gs.rTilt = gs.rTilt > -rDegQuad ? gs.rTilt-TILTSTEP : -rDegQuad;
  1171.       wi.fRedraw = fTrue;
  1172.     }
  1173.     us.fGraphics = fTrue;
  1174.     break;
  1175.  
  1176.   case cmdTiltIncrease:
  1177.     if (gi.nMode != gGlobe)
  1178.       wi.nMode = gGlobe;
  1179.     if (gs.rTilt < rDegQuad) {
  1180.       gs.rTilt = gs.rTilt < rDegQuad ? gs.rTilt+TILTSTEP : rDegQuad;
  1181.       wi.fRedraw = fTrue;
  1182.     }
  1183.     us.fGraphics = fTrue;
  1184.     break;
  1185.  
  1186.   case cmdGraphicsModify:
  1187.     not(gs.fAlt);
  1188.     WiCheckMenu(cmdGraphicsModify, gs.fAlt);
  1189.     us.fGraphics = wi.fRedraw = fTrue;
  1190.     break;
  1191.  
  1192.   case cmdChartModify:
  1193.     not(us.fPrimeVert);
  1194.     not(us.fCalendarYear);
  1195.     not(us.nEphemYears);
  1196.     not(gs.fMollewide);
  1197.     gi.nMode = (gi.nMode == gWheel ? gHouse :
  1198.       (gi.nMode == gHouse ? gWheel : gi.nMode));
  1199.     us.fGraphics = wi.fRedraw = fTrue;
  1200.     break;
  1201.  
  1202.   case cmdPen0:
  1203.   case cmdPen1:
  1204.   case cmdPen2:
  1205.   case cmdPen3:
  1206.   case cmdPen4:
  1207.   case cmdPen5:
  1208.   case cmdPen6:
  1209.   case cmdPen7:
  1210.   case cmdPen8:
  1211.   case cmdPen9:
  1212.   case cmdPen10:
  1213.   case cmdPen11:
  1214.   case cmdPen12:
  1215.   case cmdPen13:
  1216.   case cmdPen14:
  1217.   case cmdPen15:
  1218.     WiCheckMenu(cmdPen0 + wi.kiPen, fFalse);
  1219.     wi.kiPen = (int)(wCmd - cmdPen0);
  1220.     WiCheckMenu(wCmd, fTrue);
  1221.     break;
  1222.  
  1223.   case cmdSettingGraphics:
  1224.     WiDoDialog(DlgGraphics, dlgGraphics);
  1225.     break;
  1226.  
  1227.   /* Animate Menu */
  1228.  
  1229.   case cmdAnimateNo:
  1230.   case cmdAnimateNow:
  1231.     WiCheckMenu(cmdAnimateNo + gs.nAnim, fFalse);
  1232.     if (gs.nAnim)
  1233.       gs.nAnim = 0;
  1234.     else {
  1235.       gs.nAnim = 10;
  1236.       WiCheckMenu(cmdWinBuffer, fTrue);
  1237.       wi.fBuffer = fTrue;
  1238.     }
  1239.     WiCheckMenu(cmdAnimateNo + gs.nAnim, fTrue);
  1240.     wi.fRedraw = fTrue;
  1241.     break;
  1242.  
  1243.   case cmdAnimateS1:
  1244.   case cmdAnimateS2:
  1245.   case cmdAnimateS3:
  1246.   case cmdAnimateS4:
  1247.   case cmdAnimateS5:
  1248.   case cmdAnimateS6:
  1249.   case cmdAnimateS7:
  1250.   case cmdAnimateS8:
  1251.   case cmdAnimateS9:
  1252.     WiCheckMenu(cmdAnimateNo + gs.nAnim, fFalse);
  1253.     gs.nAnim = (int)(wCmd - cmdAnimateS1) + 1;
  1254.     WiCheckMenu(wCmd, fTrue);
  1255.     WiCheckMenu(cmdWinBuffer, fTrue);
  1256.     wi.fBuffer = wi.fRedraw = fTrue;
  1257.     break;
  1258.  
  1259.   case cmdAnimateF1:
  1260.   case cmdAnimateF2:
  1261.   case cmdAnimateF3:
  1262.   case cmdAnimateF4:
  1263.   case cmdAnimateF5:
  1264.   case cmdAnimateF6:
  1265.   case cmdAnimateF7:
  1266.   case cmdAnimateF8:
  1267.   case cmdAnimateF9:
  1268.     WiCheckMenu(cmdAnimateF1 + abs(wi.nDir) - 1, fFalse);
  1269.     wi.nDir = (wi.nDir > 0 ? 1 : -1)*(int)(wCmd - cmdAnimateF1) + 1;
  1270.     WiCheckMenu(wCmd, fTrue);
  1271.     break;
  1272.  
  1273.   case cmdAnimateReverse:
  1274.     neg(wi.nDir);
  1275.     WiCheckMenu(cmdAnimateReverse, wi.nDir < 0);
  1276.     if (gs.nAnim == 0) {
  1277.       gs.nAnim = 10;
  1278.       WiCheckMenu(cmdWinBuffer, fTrue);
  1279.       WiCheckMenu(cmdAnimateNo, fFalse);
  1280.       WiCheckMenu(cmdAnimateNow, fTrue);
  1281.       wi.fBuffer = fTrue;
  1282.     }
  1283.     wi.fRedraw = fTrue;
  1284.     break;
  1285.  
  1286.   case cmdAnimatePause:
  1287.     not(wi.fPause);
  1288.     WiCheckMenu(cmdAnimatePause, wi.fPause);
  1289.     break;
  1290.  
  1291.   case cmdTimedExposure:
  1292.     not(gs.fJetTrail);
  1293.     WiCheckMenu(cmdTimedExposure, gs.fJetTrail);
  1294.     break;
  1295.  
  1296.   case cmdStepForward:
  1297.     Animate(gs.nAnim, abs(wi.nDir));
  1298.     wi.fCast = fTrue;
  1299.     break;
  1300.  
  1301.   case cmdStepBackward:
  1302.     Animate(gs.nAnim, -abs(wi.nDir));
  1303.     wi.fCast = fTrue;
  1304.     break;
  1305.  
  1306.   case cmdStore:
  1307.     ciSave = ciMain;
  1308.     break;
  1309.  
  1310.   case cmdRecall:
  1311.     ciMain = ciSave;
  1312.     wi.fCast = fTrue;
  1313.     break;
  1314.  
  1315.   /* Help Menu */
  1316.  
  1317.   case cmdDocDefault:
  1318.     WinExec("NOTEPAD ASTROLOG.DAT", SW_SHOW);
  1319.     break;
  1320.  
  1321.   case cmdDocSummary:
  1322.     WinExec("NOTEPAD FILE_ID.DIZ", SW_SHOW);
  1323.     break;
  1324.  
  1325.   case cmdDocReadme:
  1326.     WinExec("NOTEPAD README.510", SW_SHOW);
  1327.     break;
  1328.  
  1329.   case cmdDocUpdate:
  1330.     WinExec("NOTEPAD UPDATE.510", SW_SHOW);
  1331.     break;
  1332.  
  1333.   case cmdDocHelpfile:
  1334.     WinExec("WRITE HELPFILE.510", SW_SHOW);
  1335.     break;
  1336.  
  1337.   case cmdHelpSign:
  1338.     wi.nMode = gSign;
  1339.     us.fGraphics = fFalse;
  1340.     break;
  1341.  
  1342.   case cmdHelpObject:
  1343.     wi.nMode = gObject;
  1344.     us.fGraphics = fFalse;
  1345.     break;
  1346.  
  1347.   case cmdHelpAspect:
  1348.     wi.nMode = gHelpAsp;
  1349.     us.fGraphics = fFalse;
  1350.     break;
  1351.  
  1352. #ifdef CONSTEL
  1353.   case cmdHelpConstellation:
  1354.     wi.nMode = gConstel;
  1355.     us.fGraphics = fFalse;
  1356.     break;
  1357. #endif
  1358.  
  1359.   case cmdHelpPlanetInfo:
  1360.     wi.nMode = gPlanet;
  1361.     us.fGraphics = fFalse;
  1362.     break;
  1363.  
  1364. #ifdef INTERPRET
  1365.   case cmdHelpMeaning:
  1366.     wi.nMode = gMeaning;
  1367.     us.fGraphics = fFalse;
  1368.     break;
  1369. #endif
  1370.  
  1371.   case cmdHelpSwitch:
  1372.     wi.nMode = gSwitch;
  1373.     us.fGraphics = fFalse;
  1374.     break;
  1375.  
  1376.   case cmdHelpObscure:
  1377.     wi.nMode = gObscure;
  1378.     us.fGraphics = fFalse;
  1379.     break;
  1380.  
  1381.   case cmdHelpKeystroke:
  1382.     wi.nMode = gKeystroke;
  1383.     us.fGraphics = fFalse;
  1384.     break;
  1385.  
  1386.   case cmdHelpCredit:
  1387.     wi.nMode = gCredit;
  1388.     us.fGraphics = fFalse;
  1389.     break;
  1390.  
  1391.   case cmdHelpAbout:
  1392.     WiDoDialog(DlgAbout, dlgAbout);
  1393.     break;
  1394.  
  1395.   default:
  1396.     if (FBetween(wCmd, cmdMacro1, cmdMacro48)) {
  1397.       i = (int)(wCmd - cmdMacro1);
  1398.       if (szMacro[i]) {
  1399.         FProcessCommandLine(szMacro[i]);
  1400.         wi.fCast = wi.fMenuAll = fTrue;
  1401.       } else {
  1402.         sprintf(sz, "Macro number %d is not defined.", i+1);
  1403.         PrintWarning(sz);
  1404.       }
  1405.       break;
  1406.     }
  1407.     return -1;
  1408.   }
  1409.  
  1410.   if (us.fNoGraphics)
  1411.     us.fGraphics = fFalse;
  1412.   if (us.fGraphics != fGraphics)
  1413.     WiCheckMenu(cmdGraphics, us.fGraphics);
  1414.   return 0;
  1415. }
  1416.  
  1417.  
  1418. /* For each menu command that can have a check mark by it, determine its   */
  1419. /* state and set or clear appropriately. This is called when the program   */
  1420. /* is first started, and after commands that may change many settings that */
  1421. /* can't be kept track of, such as running macro commands or script files. */
  1422.  
  1423. void API RedoMenu()
  1424. {
  1425.   WORD cmd;
  1426.  
  1427.   CheckMenu(cmdGraphics, us.fGraphics);
  1428.   CheckMenu(cmdColoredText, us.fAnsi);
  1429.   CheckMenu(cmdWinBuffer, wi.fBuffer);
  1430.   CheckMenu(cmdWinHourglass, wi.fHourglass);
  1431.   CheckMenu(cmdChartResizesWindow, wi.fChartWindow);
  1432.   CheckMenu(cmdWindowResizesChart, wi.fWindowChart);
  1433. #ifdef INTERPRET
  1434.   CheckMenu(cmdInterpret, us.fInterpret);
  1435. #endif
  1436.   CheckMenu(cmdSecond, us.fSeconds);
  1437.   CheckMenu(cmdApplying, us.fAppSep);
  1438.   CheckMenu(cmdParallel, us.fParallel);
  1439.   for (cmd = cmdRelNo; cmd <= cmdRelProgressed; cmd++)
  1440.     CheckMenu(cmd, fFalse);
  1441.   CheckMenu(WCmdFromRc(us.nRel), fTrue);
  1442.   CheckMenu(cmdSidereal, us.fSidereal);
  1443.   CheckMenu(cmdHeliocentric, us.objCenter != 1);
  1444.   for (cmd = cmdHouse0; cmd <= cmdHouse13; cmd++)
  1445.     CheckMenu(cmd, fFalse);
  1446.   CheckMenu(cmdHouse0 + us.nHouseSystem, fTrue);
  1447.   CheckMenu(cmdHouseSetSolar, us.objOnAsc);
  1448.   CheckMenu(cmdHouseSetDecan, us.fDecan);
  1449.   CheckMenu(cmdHouseSetFlip, us.fFlip);
  1450.   CheckMenu(cmdHouseSetGeodetic, us.fGeodetic);
  1451.   CheckMenu(cmdResMinor, !ignore[oChi]);
  1452.   CheckMenu(cmdResCusp, us.fCusp);
  1453.   CheckMenu(cmdResUranian, us.fUranian);
  1454.   CheckMenu(cmdResStar, us.nStar);
  1455. #ifdef CONSTEL
  1456.   CheckMenu(cmdConstellation, gs.fConstel);
  1457. #endif
  1458.   CheckMenu(cmdGraphicsReverse, gs.fInverse);
  1459.   CheckMenu(cmdGraphicsMonochrome, !gs.fColor);
  1460.   CheckMenu(cmdGraphicsBorder, gs.fBorder);
  1461.   CheckMenu(cmdGraphicsText, gs.fText);
  1462.   CheckMenu(cmdGraphicsSidebar, !us.fVelocity);
  1463.   CheckMenu(cmdGraphicsLabel, gs.fLabel);
  1464.   for (cmd = cmdScale1; cmd <= cmdScale4; cmd++)
  1465.     CheckMenu(cmd, fFalse);
  1466.   CheckMenu(cmdScale1 + gs.nScale/100 - 1, fTrue);
  1467.   CheckMenu(cmdGraphicsModify, gs.fAlt);
  1468.   for (cmd = cmdPen0; cmd <= cmdPen15; cmd++)
  1469.     CheckMenu(cmd, fFalse);
  1470.   CheckMenu(cmdPen0 + wi.kiPen, fTrue);
  1471.   CheckMenu(cmdAnimateNow, fFalse);
  1472.   for (cmd = cmdAnimateNo; cmd <= cmdAnimateS9; cmd++)
  1473.     CheckMenu(cmd, fFalse);
  1474.   CheckMenu(cmdAnimateNo + gs.nAnim, fTrue);
  1475.   for (cmd = cmdAnimateF1; cmd <= cmdAnimateF9; cmd++)
  1476.     CheckMenu(cmd, fFalse);
  1477.   CheckMenu(cmdAnimateF1 + abs(wi.nDir) - 1, fTrue);
  1478.   CheckMenu(cmdAnimateReverse, wi.nDir < 0);
  1479.   CheckMenu(cmdAnimatePause, wi.fPause);
  1480.   CheckMenu(cmdTimedExposure, gs.fJetTrail);
  1481.   wi.fMenuAll = fFalse;
  1482. }
  1483.  
  1484.  
  1485. /* This important routine is the bottleneck to redraw the window and call */
  1486. /* into the program to draw or do action with a particular chart type.    */
  1487.  
  1488. bool API FRedraw(void)
  1489. {
  1490.   /* Local variables used in drawing on the screen. */
  1491.   PAINTSTRUCT ps;
  1492.   HDC hdcWin;
  1493.   HCURSOR hcurOld;
  1494.   HBITMAP hbmp, hbmpOld;
  1495.   HFONT hfontOld;
  1496.   int nScrollRow, i;
  1497.  
  1498.   /* Local variables used for copying to the Windows clipboard. */
  1499.   HFILE hfile;
  1500.   LONG lSize, l;
  1501.   HGLOBAL hglobal, hmfp;
  1502.   byte HPTR *hpb;
  1503.   METAFILEPICT mfp;
  1504.  
  1505.   if (wi.fHourglass)
  1506.     hcurOld = SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
  1507.   ClearB((lpbyte)&ps, sizeof(PAINTSTRUCT));
  1508.   if (wi.hdcPrint != hdcNil)
  1509.     wi.hdc = wi.hdcPrint;
  1510.   else {
  1511.     hdcWin = BeginPaint(wi.hwnd, &ps);
  1512.     if (wi.fBuffer) {
  1513.       wi.hdc = CreateCompatibleDC(hdcWin);
  1514.       hbmp = CreateCompatibleBitmap(hdcWin, wi.xClient, wi.yClient);
  1515.       hbmpOld = SelectObject(wi.hdc, hbmp);
  1516.       if (gs.fJetTrail)
  1517.         BitBlt(wi.hdc, 0, 0, wi.xClient, wi.yClient, hdcWin, 0, 0, SRCCOPY);
  1518.     } else
  1519.       wi.hdc = hdcWin;
  1520.   }
  1521.  
  1522.   if (us.fGraphics) {
  1523.     /* Set up a graphics chart. */
  1524.     if (wi.fWindowChart && wi.hdcPrint == hdcNil) {
  1525.       gs.xWin = wi.xClient; gs.yWin = wi.yClient;
  1526.     }
  1527.     gi.nScale = gs.nScale/100;
  1528.     gi.kiCur = -1;
  1529.   } else {
  1530.     /* Set up a text chart. */
  1531.     SetWindowOrg(wi.hdc, 0, 0);
  1532.     SetWindowExt(wi.hdc, wi.xClient, wi.yClient);
  1533.     SetBkMode(wi.hdc, TRANSPARENT);
  1534.     if (wi.hdcPrint == hdcNil)
  1535.       TextClearScreen();
  1536.     i = gs.nScale/100;
  1537.     wi.xChar = i < 2 ? 6 : (i < 3 ? 8 : (i < 4 ? 10 : 12));
  1538.     wi.yChar = i < 2 ? 8 : (i < 3 ? 12 : (i < 4 ? 18 : 16));
  1539.     wi.hfont = CreateFont(wi.yChar /*nHeight*/, wi.xChar /*nWidth*/,
  1540.       0 /*nEscapement*/, 0 /*nOrientation*/, FW_DONTCARE,
  1541.       0 /*fbItalic*/, 0 /*fbUnderline*/, 0 /*fbStrikeOut*/,
  1542.       DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_DEFAULT_PRECIS,
  1543.       DRAFT_QUALITY, FIXED_PITCH | FF_DONTCARE, "Terminal");
  1544.     hfontOld = SelectObject(wi.hdc, wi.hfont);
  1545.     /* If printing, set the number of text rows per page. */
  1546.     if (wi.hdcPrint != hdcNil) {
  1547.       nScrollRow = us.nScrollRow;
  1548.       us.nScrollRow = wi.yClient / wi.yChar;
  1549.     }
  1550.   }
  1551.  
  1552.   Action();    /* Actually go and create the chart here. */
  1553.  
  1554.   /* Cleanup and copy from the buffer to the screen if need be. */
  1555.  
  1556.   if (!us.fGraphics) {
  1557.     if (wi.hdcPrint != hdcNil)
  1558.       us.nScrollRow = nScrollRow;
  1559.     SelectObject(wi.hdc, hfontOld);
  1560.     DeleteObject(wi.hfont);
  1561.   }
  1562.   if (wi.hdcPrint == hdcNil) {
  1563.     if (wi.fBuffer) {
  1564.       BitBlt(hdcWin, 0, 0, wi.xClient, wi.yClient, wi.hdc, 0, 0, SRCCOPY);
  1565.       SelectObject(wi.hdc, hbmpOld);
  1566.       DeleteObject(hbmp);
  1567.       DeleteDC(wi.hdc);
  1568.     }
  1569.     EndPaint(wi.hwnd, &ps);
  1570.   }
  1571.   if (wi.fHourglass)
  1572.     SetCursor(hcurOld);
  1573.  
  1574.   /* Sometimes creating a chart means saving it to a file instead of     */
  1575.   /* drawing it on screen. If we were in file mode, cleanup things here. */
  1576.  
  1577.   if (is.szFileScreen != NULL || gs.fBitmap || gs.fMeta || gs.fPS) {
  1578.     is.szFileScreen = NULL;
  1579.     if (gs.fMeta) {
  1580.       gs.xWin /= METAMUL; gs.yWin /= METAMUL; gs.nScale /= METAMUL;
  1581.     } else if (gs.fPS) {
  1582.       gs.xWin /= PSMUL; gs.yWin /= PSMUL; gs.nScale /= PSMUL;
  1583.     }
  1584.     gs.fBitmap = gs.fMeta = gs.fPS = fFalse;
  1585.  
  1586.     /* To copy charts to the clipboard, Astrolog saves the chart to a temp */
  1587.     /* file, then copies the contents of that file to the cllipboard.      */
  1588.  
  1589.     if (wi.wCmd == cmdCopyText || wi.wCmd == cmdCopyBitmap ||
  1590.       wi.wCmd == cmdCopyPicture || wi.wCmd == cmdCopyPS) {
  1591.       hfile = _lopen(szFileTemp, READ);
  1592.       if (hfile == HFILE_ERROR)
  1593.         return fFalse;
  1594.       lSize = _llseek(hfile, 0, 2);
  1595.       /* For bitmap and metafile charts, skip over the file header bytes. */
  1596.       l = wi.wCmd == cmdCopyBitmap ? sizeof(BITMAPFILEHEADER) :
  1597.         (wi.wCmd == cmdCopyPicture ? 22 : 0);
  1598.       hglobal = GlobalAlloc(GMEM_MOVEABLE, lSize - l);
  1599.       if (hglobal == (HGLOBAL)NULL)
  1600.         return fFalse;
  1601.       hpb = GlobalLock(hglobal);
  1602.       _llseek(hfile, l, 0);
  1603.       _hread(hfile, hpb, lSize - l);
  1604.       _lclose(hfile);
  1605.       GlobalUnlock(hglobal);
  1606.       if (!OpenClipboard(wi.hwnd))
  1607.         return fFalse;
  1608.       EmptyClipboard();
  1609.       if (wi.wCmd == cmdCopyText || wi.wCmd == cmdCopyPS)
  1610.         SetClipboardData(CF_TEXT, hglobal);
  1611.       else if (wi.wCmd == cmdCopyBitmap)
  1612.         SetClipboardData(CF_DIB, hglobal);
  1613.       else {
  1614.         mfp.mm = MM_ANISOTROPIC;  /* For metafiles a special structure  */
  1615.         mfp.xExt = -gs.xWin;      /* with a pointer to the picture data */
  1616.         mfp.yExt = -gs.yWin;      /* needs to be allocated and used.    */
  1617.         mfp.hMF = hglobal;
  1618.         hmfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT));
  1619.         if (hmfp == (HGLOBAL)NULL)
  1620.           return fFalse;
  1621.         hpb = GlobalLock(hmfp);
  1622.         *(METAFILEPICT *)hpb = mfp;
  1623.         GlobalUnlock(hmfp);
  1624.         SetClipboardData(CF_METAFILEPICT, hmfp);
  1625.       }
  1626.       CloseClipboard();
  1627.       _unlink(szFileTemp);
  1628.       wi.wCmd = 0;
  1629.     }
  1630.     ProcessState();
  1631.   }
  1632.  
  1633.   wi.fRedraw = fFalse;
  1634.   return fTrue;
  1635. }
  1636. #endif /* WIN */
  1637.  
  1638. /* wdriver.c */
  1639.